<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>高维数据PCA降维分析</title>
	<script>
	    window.MathJax = {
	      tex: { inlineMath: [['\\(', '\\)']], displayMath: [['$$', '$$']] },
	      options: { skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre'] }
	    };
	  </script>
	  <script id="MathJax-script" async
	          src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
	</script>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/js/all.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/3.0.3/plotly.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vanta/0.5.24/vanta.birds.min.js"></script>
    <style>
        .gradient-text {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
        }
        .glass-effect {
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.2);
        }
        .hero-bg {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 60vh;
        }
        .card-hover {
            transition: all 0.3s ease;
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
        }
        .math-formula {
            background: #f8f9fa;
            border-left: 4px solid #667eea;
            padding: 1rem;
            margin: 1rem 0;
            border-radius: 0 8px 8px 0;
        }
        .code-block {
            background: #1a1a1a;
            color: #f8f8f2;
            padding: 1.5rem;
            border-radius: 8px;
            overflow-x: auto;
            font-family: 'Courier New', monospace;
        }
        .interactive-element {
            cursor: pointer;
            transition: all 0.3s ease;
        }
        .interactive-element:hover {
            background: rgba(102, 126, 234, 0.1);
            border-radius: 8px;
        }
        .tab-content {
            display: none;
        }
        .tab-content.active {
            display: block;
        }
        .tab-button {
            transition: all 0.3s ease;
        }
        .tab-button.active {
            background: #667eea;
            color: white;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- 导航栏 -->
    <nav class="fixed top-0 w-full bg-white shadow-lg z-50">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
            <div class="flex justify-between h-16">
                <div class="flex items-center">
                    <i class="fas fa-chart-line text-2xl text-indigo-600 mr-3"></i>
                    <span class="text-xl font-bold text-gray-900">人工智能与机器学习作业——PCA降维分析(以5只知名股票为例)</span>
                </div>
                <div class="flex items-center space-x-8">
                    <a href="#overview" class="text-gray-700 hover:text-indigo-600 transition-colors">概述</a>
                    <a href="#data" class="text-gray-700 hover:text-indigo-600 transition-colors">数据</a>
                    <a href="#analysis" class="text-gray-700 hover:text-indigo-600 transition-colors">分析</a>
                    <a href="#results" class="text-gray-700 hover:text-indigo-600 transition-colors">结果</a>
                    <a href="#code" class="text-gray-700 hover:text-indigo-600 transition-colors">代码</a>
                    <!-- <span class="text-gray-700 font-medium">QZ251_2025720841_徐中秋</span> -->
                </div>
            </div>
        </div>
    </nav>

    <!-- 主要内容 -->
    <main class="pt-16">
        <!-- 概述部分 -->
        <section id="overview" class="hero-bg flex items-center justify-center text-white">
            <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20">
                <div class="text-center">
                    <h1 class="text-5xl font-bold mb-6 text-yellow-300">
                        高维数据PCA降维分析
                    </h1>
                    <p class="text-xl mb-8 max-w-3xl mx-auto leading-relaxed">
                        通过从零实现的主成分分析(PCA)算法，将25维股票数据降维到7维，保留了95.29%的原始信息。
                        本分析完整展示了PCA的数学原理和代码实现过程。
                    </p>
                    <div class="grid grid-cols-1 md:grid-cols-4 gap-6 mt-12">
                        <div class="glass-effect p-6 rounded-lg text-center">
                            <div class="text-3xl font-bold">25</div>
                            <div class="text-sm opacity-90">原始维度</div>
                        </div>
                        <div class="glass-effect p-6 rounded-lg text-center">
                            <div class="text-3xl font-bold">7</div>
                            <div class="text-sm opacity-90">降维后维度</div>
                        </div>
                        <div class="glass-effect p-6 rounded-lg text-center">
                            <div class="text-3xl font-bold">95.29%</div>
                            <div class="text-sm opacity-90">信息保留率</div>
                        </div>
                        <div class="glass-effect p-6 rounded-lg text-center">
                            <div class="text-3xl font-bold">72%</div>
                            <div class="text-sm opacity-90">维度减少率</div>
                        </div>
                    </div>
                    <div class="mt-8 text-center">
                        <span class="text-lg text-white opacity-80">2025720841_徐中秋</span>
                    </div>
                </div>
            </div>
        </section>

        <!-- 高维数据解释 -->
        <section class="py-16 bg-white">
            <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
                
                
                <div class="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
                    <div class="space-y-6">
                        <div class="interactive-element p-6 rounded-lg">
                            <h3 class="text-xl font-semibold mb-3 text-indigo-600">
                                <i class="fas fa-cube mr-2"></i>维度构建
                            </h3>
                            <p class="text-gray-700">
                                在我的分析中，每只股票的5个特征（开、高、低、收、成交量）
                                乘以5只股票，构成了25维的特征空间。
                            </p>
                        </div>
                        
                        <div class="interactive-element p-6 rounded-lg">
                            <h3 class="text-xl font-semibold mb-3 text-indigo-600">
                                <i class="fas fa-exclamation-triangle mr-2"></i>维度灾难
                            </h3>
                            <p class="text-gray-700">
                                当维度增加时，数据点之间的距离变得越来越稀疏，
                                导致传统分析方法失效，这就是"维度灾难"。
                            </p>
                        </div>
                        
                        <div class="interactive-element p-6 rounded-lg">
                            <h3 class="text-xl font-semibold mb-3 text-indigo-600">
                                <i class="fas fa-compress-arrows-alt mr-2"></i>降维需求
                            </h3>
                            <p class="text-gray-700">
                                通过降维，我们可以保留数据的主要信息，
                                同时减少计算复杂度和存储需求。
                            </p>
                        </div>
                    </div>
                    
                    <div class="bg-gray-100 p-8 rounded-lg">
                        <h4 class="text-lg font-semibold mb-4">维度构成示意</h4>
                        <div class="space-y-3">
                            <div class="flex items-center justify-between p-3 bg-white rounded">
                                <span class="font-medium">AAPL_Open</span>
                                <span class="text-sm text-gray-500">维度 1</span>
                            </div>
                            <div class="flex items-center justify-between p-3 bg-white rounded">
                                <span class="font-medium">AAPL_High</span>
                                <span class="text-sm text-gray-500">维度 2</span>
                            </div>
                            <div class="flex items-center justify-between p-3 bg-white rounded">
                                <span class="font-medium">AAPL_Low</span>
                                <span class="text-sm text-gray-500">维度 3</span>
                            </div>
                            <div class="flex items-center justify-between p-3 bg-white rounded">
                                <span class="font-medium">AAPL_Close</span>
                                <span class="text-sm text-gray-500">维度 4</span>
                            </div>
                            <div class="flex items-center justify-between p-3 bg-white rounded">
                                <span class="font-medium">AAPL_Volume</span>
                                <span class="text-sm text-gray-500">维度 5</span>
                            </div>
                            <div class="text-center py-2 text-gray-500">...</div>
                            <div class="flex items-center justify-between p-3 bg-white rounded">
                                <span class="font-medium">TSLA_Volume</span>
                                <span class="text-sm text-gray-500">维度 25</span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- 数据展示 -->
        <section id="data" class="py-16 bg-gray-50">
            <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
                <div class="text-center mb-12">
                    <h2 class="text-3xl font-bold text-gray-900 mb-4">数据集概览</h2>
                    <p class="text-lg text-gray-600">我使用了5只知名科技股的一年历史数据</p>
                </div>
                
                <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-6 mb-12">
                    <div class="card-hover bg-white p-6 rounded-lg shadow-lg text-center">
                        <div class="text-4xl mb-4">🍎</div>
                        <h3 class="text-xl font-bold text-gray-900 mb-2">AAPL</h3>
                        <p class="text-gray-600 text-sm">Apple Inc.</p>
                        <div class="mt-4 text-sm text-gray-500">
                            <div>250个交易日</div>
                            <div>5个特征维度</div>
                        </div>
                    </div>
                    
                    <div class="card-hover bg-white p-6 rounded-lg shadow-lg text-center">
                        <div class="text-4xl mb-4">🔍</div>
                        <h3 class="text-xl font-bold text-gray-900 mb-2">GOOGL</h3>
                        <p class="text-gray-600 text-sm">Alphabet Inc.</p>
                        <div class="mt-4 text-sm text-gray-500">
                            <div>250个交易日</div>
                            <div>5个特征维度</div>
                        </div>
                    </div>
                    
                    <div class="card-hover bg-white p-6 rounded-lg shadow-lg text-center">
                        <div class="text-4xl mb-4">🪟</div>
                        <h3 class="text-xl font-bold text-gray-900 mb-2">MSFT</h3>
                        <p class="text-gray-600 text-sm">Microsoft Corp.</p>
                        <div class="mt-4 text-sm text-gray-500">
                            <div>250个交易日</div>
                            <div>5个特征维度</div>
                        </div>
                    </div>
                    
                    <div class="card-hover bg-white p-6 rounded-lg shadow-lg text-center">
                        <div class="text-4xl mb-4">📦</div>
                        <h3 class="text-xl font-bold text-gray-900 mb-2">AMZN</h3>
                        <p class="text-gray-600 text-sm">Amazon.com Inc.</p>
                        <div class="mt-4 text-sm text-gray-500">
                            <div>250个交易日</div>
                            <div>5个特征维度</div>
                        </div>
                    </div>
                    
                    <div class="card-hover bg-white p-6 rounded-lg shadow-lg text-center">
                        <div class="text-4xl mb-4">⚡</div>
                        <h3 class="text-xl font-bold text-gray-900 mb-2">TSLA</h3>
                        <p class="text-gray-600 text-sm">Tesla Inc.</p>
                        <div class="mt-4 text-sm text-gray-500">
                            <div>250个交易日</div>
                            <div>5个特征维度</div>
                        </div>
                    </div>
                </div>
                
                <div class="bg-white p-8 rounded-lg shadow-lg">
                    <h3 class="text-2xl font-bold mb-6 text-center">数据特征矩阵</h3>
                    <div class="overflow-x-auto">
                        <table class="w-full border-collapse">
                            <thead>
                                <tr class="bg-gray-50">
                                    <th class="border p-3 text-left">股票代码</th>
                                    <th class="border p-3 text-center">开盘价</th>
                                    <th class="border p-3 text-center">最高价</th>
                                    <th class="border p-3 text-center">最低价</th>
                                    <th class="border p-3 text-center">收盘价</th>
                                    <th class="border p-3 text-center">成交量</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr>
                                    <td class="border p-3 font-medium">AAPL</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                </tr>
                                <tr class="bg-gray-50">
                                    <td class="border p-3 font-medium">GOOGL</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                </tr>
                                <tr>
                                    <td class="border p-3 font-medium">MSFT</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                </tr>
                                <tr class="bg-gray-50">
                                    <td class="border p-3 font-medium">AMZN</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                </tr>
                                <tr>
                                    <td class="border p-3 font-medium">TSLA</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                    <td class="border p-3 text-center">✓</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                    <div class="mt-6 text-center text-gray-600">
                        <p>总计：5只股票 × 5个特征 = 25维特征空间</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- PCA分析过程 -->
        <section id="analysis" class="py-16 bg-white">
            <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
                <div class="text-center mb-12">
                    <h2 class="text-3xl font-bold text-gray-900 mb-4">PCA分析过程</h2>
                    <p class="text-lg text-gray-600">主成分分析的数学原理和实现步骤</p>
                </div>
                
                <!-- PCA步骤 -->
                <div class="grid grid-cols-1 lg:grid-cols-2 gap-12 mb-16">
                  <div class="space-y-8">
                    <!-- 1 -->
                    <div class="interactive-element p-6 rounded-lg">
                      <div class="flex items-center mb-4">
                        <div class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-4">
                          <span class="text-sm font-bold">1</span>
                        </div>
                        <h3 class="text-xl font-semibold">数据标准化</h3>
                      </div>
                      <div class="math-formula">
                        $$ X_{\text{std}} = \frac{X - \mu}{\sigma} $$
                      </div>
                      <p class="text-gray-700">
                        对每个特征进行Z-score标准化，消除量纲差异，确保所有特征在相同尺度上参与分析。
                      </p>
                    </div>
                
                    <!-- 2 -->
                    <div class="interactive-element p-6 rounded-lg">
                      <div class="flex items-center mb-4">
                        <div class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-4">
                          <span class="text-sm font-bold">2</span>
                        </div>
                        <h3 class="text-xl font-semibold">协方差矩阵计算</h3>
                      </div>
                      <div class="math-formula">
                        $$ C = \frac{1}{n-1} X_{\text{std}}^T X_{\text{std}} $$
                      </div>
                      <p class="text-gray-700">
                        计算标准化数据的协方差矩阵，捕捉各特征之间的线性关系。
                      </p>
                    </div>
                
                    <!-- 3 -->
                    <div class="interactive-element p-6 rounded-lg">
                      <div class="flex items-center mb-4">
                        <div class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-4">
                          <span class="text-sm font-bold">3</span>
                        </div>
                        <h3 class="text-xl font-semibold">特征值分解</h3>
                      </div>
                      <div class="math-formula">
                        $$ C = V \Lambda V^T $$
                      </div>
                      <p class="text-gray-700">
                        对协方差矩阵进行特征值分解，得到特征值和对应的特征向量。
                      </p>
                    </div>
                
                    <!-- 4 -->
                    <div class="interactive-element p-6 rounded-lg">
                      <div class="flex items-center mb-4">
                        <div class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-4">
                          <span class="text-sm font-bold">4</span>
                        </div>
                        <h3 class="text-xl font-semibold">主成分选择</h3>
                      </div>
                      <p class="text-gray-700">
                        按特征值大小排序，选择前k个最大特征值对应的特征向量作为主成分。
                      </p>
                    </div>
                
                    <!-- 5 -->
                    <div class="interactive-element p-6 rounded-lg">
                      <div class="flex items-center mb-4">
                        <div class="w-8 h-8 bg-indigo-600 text-white rounded-full flex items-center justify-center mr-4">
                          <span class="text-sm font-bold">5</span>
                        </div>
                        <h3 class="text-xl font-semibold">数据投影</h3>
                      </div>
                      <div class="math-formula">
                        $$ Z = X_{\text{std}} W $$
                      </div>
                      <p class="text-gray-700">
                        将原始数据投影到选定的主成分空间，得到降维后的数据表示。
                      </p>
                    </div>
                  </div>
                    
                    <div class="bg-gray-50 p-8 rounded-lg">
                        <h4 class="text-xl font-semibold mb-6 text-center">PCA可视化示意</h4>
                        <div class="space-y-6">
                            <div class="text-center">
                                <div class="inline-block p-4 bg-blue-100 rounded-lg mb-4">
                                    <i class="fas fa-cube text-4xl text-blue-600"></i>
                                </div>
                                <h5 class="font-medium mb-2">高维数据空间</h5>
                                <p class="text-sm text-gray-600">25维特征空间</p>
                            </div>
                            
                            <div class="flex justify-center">
                                <i class="fas fa-arrow-down text-2xl text-gray-400"></i>
                            </div>
                            
                            <div class="text-center">
                                <div class="inline-block p-4 bg-green-100 rounded-lg mb-4">
                                    <i class="fas fa-compress-arrows-alt text-4xl text-green-600"></i>
                                </div>
                                <h5 class="font-medium mb-2">PCA变换</h5>
                                <p class="text-sm text-gray-600">寻找最大方差方向</p>
                            </div>
                            
                            <div class="flex justify-center">
                                <i class="fas fa-arrow-down text-2xl text-gray-400"></i>
                            </div>
                            
                            <div class="text-center">
                                <div class="inline-block p-4 bg-purple-100 rounded-lg mb-4">
                                    <i class="fas fa-chart-line text-4xl text-purple-600"></i>
                                </div>
                                <h5 class="font-medium mb-2">低维空间</h5>
                                <p class="text-sm text-gray-600">7维主成分空间</p>
                            </div>
                        </div>
                    </div>
                </div>
                
                <!-- 方差解释图 -->
                <div class="bg-white p-8 rounded-lg shadow-lg">
                    <h3 class="text-2xl font-bold mb-6 text-center">主成分方差解释</h3>
                    <div id="varianceChart" style="height: 500px;"></div>
                </div>
            </div>
        </section>

        <!-- 结果展示 -->
        <section id="results" class="py-16 bg-gray-50">
            <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
                <div class="text-center mb-12">
                    <h2 class="text-3xl font-bold text-gray-900 mb-4">分析结果</h2>
                    <p class="text-lg text-gray-600">PCA降维的主要发现</p>
                </div>
                
                <!-- 关键指标 -->
                <div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-12">
                    <div class="card-hover bg-white p-6 rounded-lg shadow-lg text-center">
                        <div class="text-3xl font-bold text-indigo-600 mb-2">53.76%</div>
                        <div class="text-gray-600 mb-2">第一主成分</div>
                        <div class="text-sm text-gray-500">解释最大方差</div>
                    </div>
                    <div class="card-hover bg-white p-6 rounded-lg shadow-lg text-center">
                        <div class="text-3xl font-bold text-green-600 mb-2">79.73%</div>
                        <div class="text-gray-600 mb-2">前3个主成分</div>
                        <div class="text-sm text-gray-500">累积方差解释</div>
                    </div>
                    <div class="card-hover bg-white p-6 rounded-lg shadow-lg text-center">
                        <div class="text-3xl font-bold text-purple-600 mb-2">95.29%</div>
                        <div class="text-gray-600 mb-2">前7个主成分</div>
                        <div class="text-sm text-gray-500">信息保留率</div>
                    </div>
                    <div class="card-hover bg-white p-6 rounded-lg shadow-lg text-center">
                        <div class="text-3xl font-bold text-red-600 mb-2">4.71%</div>
                        <div class="text-gray-600 mb-2">信息损失</div>
                        <div class="text-sm text-gray-500">降维代价</div>
                    </div>
                </div>
                
                <!-- 可视化图表 -->
                <div class="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-12">
                    <div class="bg-white p-6 rounded-lg shadow-lg">
                        <h3 class="text-xl font-semibold mb-4">方差解释比例</h3>
                        <img src="from_scratch_charts/pca_variance_analysis_from_scratch.png" alt="PCA方差分析" class="w-full rounded-lg">
                    </div>
                    <div class="bg-white p-6 rounded-lg shadow-lg">
                        <h3 class="text-xl font-semibold mb-4">综合PCA分析</h3>
                        <img src="from_scratch_charts/pca_comprehensive_analysis_from_scratch.png" alt="PCA综合分析" class="w-full rounded-lg">
                    </div>
                </div>
                
                <!-- 主成分解释 -->
                <div class="bg-white p-8 rounded-lg shadow-lg">
                    <h3 class="text-2xl font-bold mb-8 text-center">主成分经济解释</h3>
                    <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
                        <div class="text-center">
                            <div class="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-4">
                                <i class="fas fa-chart-line text-2xl text-blue-600"></i>
                            </div>
                            <h4 class="text-lg font-semibold mb-3">第一主成分 (53.76%)</h4>
                            <p class="text-gray-700 text-sm">
                                代表整体科技股市场的共同趋势，
                                所有股票的价格特征都呈现正相关。
                            </p>
                        </div>
                        
                        <div class="text-center">
                            <div class="w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4">
                                <i class="fas fa-bolt text-2xl text-green-600"></i>
                            </div>
                            <h4 class="text-lg font-semibold mb-3">第二主成分 (16.01%)</h4>
                            <p class="text-gray-700 text-sm">
                                主要反映Tesla相对于其他股票的特殊运动，
                                捕捉Tesla的独特风险和机会。
                            </p>
                        </div>
                        
                        <div class="text-center">
                            <div class="w-16 h-16 bg-purple-100 rounded-full flex items-center justify-center mx-auto mb-4">
                                <i class="fas fa-exchange-alt text-2xl text-purple-600"></i>
                            </div>
                            <h4 class="text-lg font-semibold mb-3">第三主成分 (9.96%)</h4>
                            <p class="text-gray-700 text-sm">
                                主要与成交量特征相关，
                                反映市场流动性和交易活跃度变化。
                            </p>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- 代码实现 -->
        <section id="code" class="py-16 bg-white">
            <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
                <div class="text-center mb-12">
                    <h2 class="text-3xl font-bold text-gray-900 mb-4">代码实现</h2>
                    <p class="text-lg text-gray-600">PCA算法，包含完整的数学推导和数值优化</p>
                </div>
                
                <!-- 代码标签页 -->
                <div class="bg-gray-100 p-8 rounded-lg">
                    <div class="flex space-x-4 mb-6">
                        <button class="tab-button active px-4 py-2 bg-white text-gray-700 rounded-lg" onclick="showTab('pca-scratch')">
                            PCA的实现
                        </button>
                        <button class="tab-button px-4 py-2 bg-white text-gray-700 rounded-lg" onclick="showTab('mathematical-steps')">
                            数学步骤
                        </button>
                        <button class="tab-button px-4 py-2 bg-white text-gray-700 rounded-lg" onclick="showTab('verification')">
                            验证方法
                        </button>
                        <button class="tab-button px-4 py-2 bg-white text-gray-700 rounded-lg" onclick="showTab('usage-example')">
                            使用示例
                        </button>
                    </div>
                    
                    <div class="tab-content active" id="pca-scratch">
                        <div class="code-block">
<pre><code>import numpy as np
from sklearn.preprocessing import StandardScaler

class PCAFromScratch:
    """
    从零实现的PCA算法
    包含完整的数学推导步骤和数值优化
    """
    
    def __init__(self, n_components=None, random_state=None):
        self.n_components = n_components
        self.random_state = random_state
        self.mean_ = None
        self.components_ = None
        self.explained_variance_ = None
        self.explained_variance_ratio_ = None
        self.singular_values_ = None
        
    def fit(self, X):
        """拟合PCA模型"""
        # 1. 数据验证和预处理
        X = np.asarray(X, dtype=np.float64)
        n_samples, n_features = X.shape
        
        if self.n_components is None:
            self.n_components = min(n_samples, n_features)
        elif not 1 <= self.n_components <= min(n_samples, n_features):
            raise ValueError(f"n_components={self.n_components} 必须在1和{min(n_samples, n_features)}之间")
        
        # 2. 计算均值并进行中心化处理
        self.mean_ = np.mean(X, axis=0)
        X_centered = X - self.mean_
        
        # 3. 构建协方差矩阵
        if n_samples > n_features:
            covariance_matrix = np.cov(X_centered.T)
        else:
            covariance_matrix = (X_centered.T @ X_centered) / (n_samples - 1)
        
        # 4. 特征值分解 - 使用稳定的方法
        eigenvalues, eigenvectors = self._stable_eigendecomposition(covariance_matrix)
        
        # 5. 排序特征值和特征向量（降序）
        idx = np.argsort(eigenvalues)[::-1]
        eigenvalues = eigenvalues[idx]
        eigenvectors = eigenvectors[:, idx]
        
        # 6. 选择前n_components个主成分
        self.components_ = eigenvectors[:, :self.n_components].T
        self.explained_variance_ = eigenvalues[:self.n_components]
        
        # 7. 计算解释方差比例
        total_variance = np.sum(eigenvalues)
        self.explained_variance_ratio_ = self.explained_variance_ / total_variance
        
        # 8. 计算奇异值
        self.singular_values_ = np.sqrt(self.explained_variance_ * (n_samples - 1))
        
        return self
    
    def _stable_eigendecomposition(self, matrix):
        """稳定的特征值分解实现"""
        try:
            # 方法1：使用numpy的eigh（适用于对称矩阵）
            eigenvalues, eigenvectors = np.linalg.eigh(matrix)
            return eigenvalues, eigenvectors
        except np.linalg.LinAlgError:
            try:
                # 方法2：使用numpy的eig（通用方法）
                eigenvalues, eigenvectors = np.linalg.eig(matrix)
                return eigenvalues, eigenvectors
            except np.linalg.LinAlgError:
                # 方法3：使用SVD分解
                U, S, Vt = np.linalg.svd(matrix)
                eigenvalues = S ** 2 / (matrix.shape[0] - 1)
                eigenvectors = Vt.T
                return eigenvalues, eigenvectors
    
    def transform(self, X):
        """将数据转换到主成分空间"""
        X = np.asarray(X, dtype=np.float64)
        X_centered = X - self.mean_
        return X_centered @ self.components_.T
    
    def fit_transform(self, X):
        """拟合模型并转换数据"""
        return self.fit(X).transform(X)
    
    def inverse_transform(self, X_transformed):
        """将降维数据转换回原始空间"""
        X_transformed = np.asarray(X_transformed, dtype=np.float64)
        return X_transformed @ self.components_ + self.mean_</code></pre>
                        </div>
                    </div>
                    
                    <div class="tab-content" id="mathematical-steps">
                        <div class="code-block">
<pre><code># PCA数学步骤详细实现

# 步骤1: 数据标准化
scaler = StandardScaler()
X_std = scaler.fit_transform(X)

# 步骤2: 计算协方差矩阵
n_samples = X_std.shape[0]
covariance_matrix = np.cov(X_std.T)

# 步骤3: 特征值分解
eigenvalues, eigenvectors = np.linalg.eigh(covariance_matrix)

# 步骤4: 排序（降序）
idx = np.argsort(eigenvalues)[::-1]
eigenvalues = eigenvalues[idx]
eigenvectors = eigenvectors[:, idx]

# 步骤5: 选择主成分
n_components = 7
components = eigenvectors[:, :n_components].T
explained_variance = eigenvalues[:n_components]

# 步骤6: 计算解释方差比例
total_variance = np.sum(eigenvalues)
explained_variance_ratio = explained_variance / total_variance

# 步骤7: 数据投影
X_reduced = X_std @ components.T

# 步骤8: 验证结果
print(f"原始维度: {X.shape[1]}")
print(f"降维后维度: {X_reduced.shape[1]}")
print(f"保留信息: {np.sum(explained_variance_ratio):.2%}")</code></pre>
                        </div>
                    </div>
                    
                    <div class="tab-content" id="verification">
                        <div class="code-block">
<pre><code># PCA实现验证方法

def verify_implementation(pca_model, X_std):
    """验证PCA实现的正确性"""
    
    # 1. 验证特征向量的正交性
    components = pca_model.components_
    orthogonality_check = []
    for i in range(len(components)):
        for j in range(i+1, len(components)):
            dot_product = np.dot(components[i], components[j])
            orthogonality_check.append(abs(dot_product) < 1e-10)
    
    print(f"特征向量正交性检查: {np.all(orthogonality_check)}")
    
    # 2. 验证特征向量的单位长度
    norm_check = np.allclose(np.linalg.norm(components, axis=1), 1.0)
    print(f"特征向量单位长度检查: {norm_check}")
    
    # 3. 验证方差保持性
    total_variance_original = np.sum(np.var(X_std, axis=0))
    total_variance_pca = np.sum(pca_model.explained_variance_)
    variance_preservation = np.isclose(total_variance_original, total_variance_pca, rtol=1e-5)
    print(f"方差保持性检查: {variance_preservation}")
    
    # 4. 验证降维变换
    X_transformed = pca_model.transform(X_std)
    X_reconstructed = pca_model.inverse_transform(X_transformed)
    reconstruction_error = np.mean(np.sum((X_std - X_reconstructed) ** 2, axis=1))
    print(f"重构误差: {reconstruction_error:.6f}")
    
    # 5. 验证特征值非负
    eigenvalues_nonnegative = np.all(pca_model.explained_variance_ >= 0)
    print(f"特征值非负检查: {eigenvalues_nonnegative}")
    
    return {
        'orthogonality': np.all(orthogonality_check),
        'unit_norm': norm_check,
        'variance_preservation': variance_preservation,
        'reconstruction_error': reconstruction_error,
        'eigenvalues_nonnegative': eigenvalues_nonnegative
    }

# 执行验证
verification_results = verify_implementation(pca_model, X_std)</code></pre>
                        </div>
                    </div>
                    
                    <div class="tab-content" id="usage-example">
                        <div class="code-block">
<pre><code># PCA从零实现的使用示例

# 1. 创建PCA实例
pca_scratch = PCAFromScratch(n_components=7)

# 2. 拟合和转换数据
X_reduced = pca_scratch.fit_transform(X_std)

# 3. 查看结果
print(f"降维后数据形状: {X_reduced.shape}")
print(f"解释方差比例: {pca_scratch.explained_variance_ratio_}")
print(f"累积解释方差: {np.cumsum(pca_scratch.explained_variance_ratio_)[-1]:.2%}")

# 4. 重构数据（验证信息损失）
X_reconstructed = pca_scratch.inverse_transform(X_reduced)
reconstruction_error = np.mean(np.sum((X_std - X_reconstructed) ** 2, axis=1))
print(f"重构误差: {reconstruction_error:.6f}")

# 5. 获取主成分载荷
loadings = pca_scratch.components_.T * np.sqrt(pca_scratch.explained_variance_)
print(f"载荷矩阵形状: {loadings.shape}")

# 6. 获取协方差矩阵
covariance_pca = pca_scratch.get_covariance()
print(f"PCA协方差矩阵形状: {covariance_pca.shape}")

# 7. 转换新数据
new_data_reduced = pca_scratch.transform(new_X_std)
print(f"新数据降维后形状: {new_data_reduced.shape}")

# 8. 与sklearn PCA对比
from sklearn.decomposition import PCA
pca_sklearn = PCA(n_components=7)
X_reduced_sklearn = pca_sklearn.fit_transform(X_std)

print(f"Sklearn PCA解释方差: {np.sum(pca_sklearn.explained_variance_ratio_):.2%}")
print(f"自定义PCA解释方差: {np.sum(pca_scratch.explained_variance_ratio_):.2%}")
print(f"结果差异: {np.abs(np.sum(pca_sklearn.explained_variance_ratio_) - np.sum(pca_scratch.explained_variance_ratio_)):.6f}")</code></pre>
                        </div>
                    </div>
                </div>
                
                <!-- 下载按钮 -->
                <div class="text-center mt-12">
                    <div class="space-x-4">
                        <button onclick="downloadFile('pca_from_scratch_reduced_data.csv', '降维数据.csv')" class="inline-flex items-center px-6 py-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors cursor-pointer">
                            <i class="fas fa-download mr-2"></i>
                            下载降维数据 (CSV)
                        </button>
                        <button onclick="downloadFile('pca_from_scratch_results.json', '分析结果.json')" class="inline-flex items-center px-6 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors cursor-pointer">
                            <i class="fas fa-download mr-2"></i>
                            下载分析结果 (JSON)
                        </button>
                        <button onclick="downloadFile('pca_from_scratch.py', '完整代码.py')" class="inline-flex items-center px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors cursor-pointer">
                            <i class="fas fa-download mr-2"></i>
                            下载完整代码 (PY)
                        </button>
                        <button onclick="downloadFile('高维数据PCA降维分析报告.md', '分析报告.md')" class="inline-flex items-center px-6 py-3 bg-orange-600 text-white rounded-lg hover:bg-orange-700 transition-colors cursor-pointer">
                            <i class="fas fa-download mr-2"></i>
                            下载分析报告 (MD)
                        </button>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <!-- 页脚 -->
    <footer class="bg-gray-900 text-white py-8">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
            <div class="mb-4">
                <i class="fas fa-chart-line text-2xl text-indigo-400 mr-3"></i>
                <span class="text-xl font-bold">人工智能与机器学习作业——PCA降维分析</span>
            </div>
            <p class="text-gray-400">
                © 2025/10/10 QZ251_徐中秋_2025720841
            </p>
        </div>
    </footer>

    <script>
        // 页面加载完成后的初始化
        document.addEventListener('DOMContentLoaded', function() {
            // 创建方差解释图表
            createVarianceChart();
            
            // 平滑滚动
            setupSmoothScroll();
        });

        function createVarianceChart() {
            // PCA分析结果数据
            const varianceRatio = [
                0.5376, 0.1601, 0.0996, 0.0612, 0.0383, 
                0.0296, 0.0264, 0.0197, 0.0125, 0.0114,
                0.0016, 0.0004, 0.0004, 0.0004, 0.0002,
                0.0001, 0.0001, 0.0001, 0.0001, 0.0001,
                0.0000, 0.0000, 0.0000, 0.0000, 0.0000
            ];
            
            const cumulativeRatio = varianceRatio.reduce((acc, val, i) => {
                acc.push((acc[i-1] || 0) + val);
                return acc;
            }, []);
            
            const components = Array.from({length: 25}, (_, i) => i + 1);
            
            // 创建子图
            const trace1 = {
                x: components,
                y: varianceRatio,
                type: 'bar',
                name: '方差解释比例',
                marker: {
                    color: 'rgba(102, 126, 234, 0.7)',
                    line: {
                        color: 'rgba(102, 126, 234, 1)',
                        width: 1
                    }
                }
            };
            
            const trace2 = {
                x: components,
                y: cumulativeRatio,
                type: 'scatter',
                mode: 'lines+markers',
                name: '累积方差解释比例',
                yaxis: 'y2',
                line: {
                    color: 'rgba(239, 68, 68, 1)',
                    width: 3
                },
                marker: {
                    color: 'rgba(239, 68, 68, 1)',
                    size: 8
                }
            };
            
            const layout = {
                title: {
                    text: 'PCA主成分方差解释分析（从零实现）',
                    font: { size: 18 }
                },
                xaxis: {
                    title: '主成分编号',
                    tickmode: 'linear',
                    tick0: 1,
                    dtick: 1
                },
                yaxis: {
                    title: '方差解释比例',
                    side: 'left'
                },
                yaxis2: {
                    title: '累积方差解释比例',
                    side: 'right',
                    overlaying: 'y',
                    range: [0, 1]
                },
                shapes: [
                    {
                        type: 'line',
                        x0: 0,
                        x1: 26,
                        y0: 0.95,
                        y1: 0.95,
                        yref: 'y2',
                        line: {
                            color: 'rgba(239, 68, 68, 0.7)',
                            width: 2,
                            dash: 'dash'
                        }
                    },
                    {
                        type: 'line',
                        x0: 7,
                        x1: 7,
                        y0: 0,
                        y1: 1,
                        yref: 'y2',
                        line: {
                            color: 'rgba(34, 197, 94, 0.7)',
                            width: 2,
                            dash: 'dash'
                        }
                    }
                ],
                annotations: [
                    {
                        x: 20,
                        y: 0.97,
                        yref: 'y2',
                        text: '95%阈值',
                        showarrow: false,
                        font: { color: 'rgba(239, 68, 68, 1)' }
                    },
                    {
                        x: 8,
                        y: 0.85,
                        yref: 'y2',
                        text: '7个主成分<br>保留95.29%信息',
                        showarrow: true,
                        arrowhead: 2,
                        arrowcolor: 'rgba(34, 197, 94, 1)',
                        font: { color: 'rgba(34, 197, 94, 1)' }
                    }
                ],
                showlegend: true,
                legend: {
                    x: 0.7,
                    y: 0.9
                },
                margin: { t: 60, b: 60, l: 60, r: 60 }
            };
            
            const config = {
                responsive: true,
                displayModeBar: true,
                modeBarButtonsToRemove: ['pan2d', 'lasso2d', 'select2d'],
                displaylogo: false
            };
            
            Plotly.newPlot('varianceChart', [trace1, trace2], layout, config);
        }

        function showTab(tabName) {
            // 隐藏所有标签内容
            const contents = document.querySelectorAll('.tab-content');
            contents.forEach(content => {
                content.classList.remove('active');
            });
            
            // 移除所有按钮的active类
            const buttons = document.querySelectorAll('.tab-button');
            buttons.forEach(button => {
                button.classList.remove('active');
            });
            
            // 显示选中的标签内容
            document.getElementById(tabName).classList.add('active');
            
            // 添加active类到当前按钮
            event.target.classList.add('active');
        }

        function setupSmoothScroll() {
            const links = document.querySelectorAll('a[href^="#"]');
            
            links.forEach(link => {
                link.addEventListener('click', function(e) {
                    e.preventDefault();
                    
                    const targetId = this.getAttribute('href');
                    const targetElement = document.querySelector(targetId);
                    
                    if (targetElement) {
                        const offsetTop = targetElement.offsetTop - 80; // 考虑导航栏高度
                        
                        window.scrollTo({
                            top: offsetTop,
                            behavior: 'smooth'
                        });
                    }
                });
            });
        }

        // 交互元素悬停效果
        document.querySelectorAll('.interactive-element').forEach(element => {
            element.addEventListener('mouseenter', function() {
                this.style.transform = 'translateY(-2px)';
                this.style.boxShadow = '0 10px 25px rgba(0,0,0,0.1)';
            });
            
            element.addEventListener('mouseleave', function() {
                this.style.transform = 'translateY(0)';
                this.style.boxShadow = 'none';
            });
        });

        // 文件下载功能
        async function downloadFile(filename, downloadName) {
            try {
                // 尝试使用fetch下载文件
                const response = await fetch(filename);
                
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                
                const blob = await response.blob();
                
                // 创建下载链接
                const url = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.style.display = 'none';
                a.href = url;
                a.download = downloadName;
                
                // 触发下载
                document.body.appendChild(a);
                a.click();
                
                // 清理
                window.URL.revokeObjectURL(url);
                document.body.removeChild(a);
                
            } catch (error) {
                console.error('下载失败:', error);
                
                // 如果fetch失败，尝试直接链接下载
                const a = document.createElement('a');
                a.href = filename;
                a.download = downloadName;
                a.style.display = 'none';
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                
                // 显示提示信息
                alert('正在尝试下载文件，如果失败请检查文件是否存在。');
            }
        }
    </script>
</body>
</html>